#ifndef SOUND_SYSTEM_H
#define SOUND_SYSTEM_H

#include <Ogre.h>
#include <OgreLogManager.h>
#include <map>
#include <string>

#include <FreeSL.h>

#include "Simpleton.h"

//TODO: Implement multi-listener compatibility
/*
	A little helper class to represent a sound listener positioned in 3d space
*/
class SoundListener
{
public:
	SoundListener(const Ogre::Vector3& pos,const Ogre::Quaternion& ori,const Ogre::Vector3& vel)
	{
		m_vPos=pos;
		m_qOri = ori;
		m_vVel = vel;
	}
	~SoundListener(){};

	Ogre::Vector3 getPos()const{return m_vPos;}
	Ogre::Vector3 getVel()const{return m_vVel;}
	Ogre::Quaternion getOri()const{return m_qOri;}

	void setPos(Ogre::Vector3 pos){m_vPos=pos;}
	void setVel(Ogre::Vector3 vel){m_vVel=vel;}
	void setOri(const Ogre::Quaternion& ori){m_qOri=ori;}

private:
	Ogre::Vector3 m_vPos;
	Ogre::Vector3 m_vVel;
	Ogre::Quaternion m_qOri;
};

class SoundSystem: public Simpleton<SoundSystem>
{
public:
	SoundSystem(void);
	~SoundSystem(void);

	void setFileSystem(const Ogre::String& str){m_strFileSystem=str;}
	Ogre::String getFileSystem()const{return m_strFileSystem;}

	/*
	Unloads all the sounds stored in the sound system
	*/
	void unloadAllSounds();
	/*
	Sets the volume of the sound system

	volume must be 0.0 - 1.0
	*/
	void setVolume(const float& volume);
	/*
	Loads a sound MUST DO THIS FRIST
	If a large file like a music then set bStreamed to frue to stream the audio
	*/
	void loadSound(const char* filePath,bool bStreamed=false);

	const FSLsound* playSound(const char* file,bool bLooping=false,bool bPaused=false);

	const FSLsound* play3DSound(const char* file,const Ogre::Vector3& pos,const Ogre::Vector3& velocity,const float& size,const bool& bLooping=false,const bool& bPaused=false);

	const FSLbuffer* getBuffer(const char* filePath)const;

	/*
	Update sound system
	*/
	void update(float fElapsedTime);

	/**
		Creates and sets the sound listener from the passed vectors
	**/
	SoundListener* createSoundListener(const Ogre::Quaternion& ori,const Ogre::Vector3& position,const Ogre::Vector3& velocity);
	void updateSoundListener(const Ogre::Quaternion& ori,const Ogre::Vector3& position,const Ogre::Vector3& velocity);
	/*
	Stop the sound
	*/
	void stopSound(const FSLsound* sound);

	void togglePauseAll();
private:

	typedef std::map<std::string, FSLbuffer> StrBufferMap;
	typedef std::list<FSLsound>	SoundList;

	StrBufferMap m_FileNameBufferMap;	//storing the filename as the key and the buffer object as data
	SoundList m_Sounds;		//storing the name of a sound and the sound obj

	Ogre::String m_strFileSystem;

	friend class Simpleton< SoundSystem >;

	//bool m_bActiveListener;					//whether a listener exists
	//TODO: Make multi-listener
	SoundListener* m_pListener;				//the listener

	bool m_bPauseAll;
};

#endif